﻿package src.entity {
	
	/**
	* 
	* Reliability project
	* -----------------------
	* @author  Dmitrij Boycov
	* @mail    dmitry.boycov@gmail.com
	* @date    April 27, 2010
	* @version 1
	* 
	*/
	
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.utils.Dictionary;
	import flash.geom.Point;
	import flash.filters.BlurFilter;
	
	import src.entity.Link;
	import src.computation.CNode;
	
	public class Node extends Entity implements IEntity, IObjectOfScheme {
	
		// for identification into parent scheme
		public static const TYPE:String = "NODE";		
		//
		private var cColour  = 0x222222;
		private var cRadius:Number = 5;
		private var circle:Sprite;
		private var region:Sprite;
		private var links:Dictionary = new Dictionary(true);
		
		public function Node() {
			super();			
			this.graphics.beginFill(0xffffff);
			this.graphics.drawRect(0, 0, 2 * (cRadius + indent), 2 * (cRadius + indent));			
			this.doubleClickEnabled = false;
			this.alpha = 0.6;
			this.graphics.endFill();
			this.circle = this.createCircle();			
			addChild(this.circle);
			this.name = Node.TYPE;
			//
			this.illuminateObj = new Sprite();			
			this.illuminateObj.graphics.beginFill(0x30b1e7);
			this.illuminateObj.graphics.drawCircle(cRadius+indent,cRadius+indent,cRadius+indent/2);
			this.illuminateObj.doubleClickEnabled = true;
			this.illuminateObj.graphics.endFill();
			this.illuminateObj.filters =[new BlurFilter(5,5,3)];
		}
		
		
		// geters		
		public override function getType():String{
			return Node.TYPE;
		}
		
		public function getLinks():Dictionary {
			return this.links;
		}
		///
		public function addLink(link:Link):Boolean {
			var l = link.getEndEntity();
			if (l == null) l = link.getStartEntity();
			if (l == this) return false;
			if(l!=null){
				var p:Link;
				for each(p in links){
					if (l == p.getEndEntity()) return false;
					if (l == p.getStartEntity()) return false;
				}
			}
			links[link.getId()] = link;
			return true;
		}
		
		public function getPointOutSide(p:Point, p2:Point):Point {
			var x1, y1:Number;
			var pc = new Point(cRadius + indent, cRadius + indent);
			var pn = new Point(this.x, this.y);
			pc = this.localToGlobal(pc);
			if (p2.x <= pc.x && p2.y >= pc.y) {
				x1 = pn.x; y1 = pn.y+this.height;
			}
			if (p2.x >= pc.x && p2.y <= pc.y) {
				x1 = pn.x + this.width; y1 = pn.y;
			}
			if (p2.x >= pc.x && p2.y >= pc.y) {
				x1 = pn.x + this.width; y1 = pn.y+this.height;
			}
			if (p2.x <= pc.x && p2.y <= pc.y) {
				x1 = pn.x; y1 = pn.y;
			}
			var p1 = new Point(x1, y1);			
			return p1;
		}
		
		public function getConnectPoint(p:Point, p2:Point,l:Link ):Point {			
			var x1, y1:Number;
			var pc = new Point(cRadius + indent, cRadius + indent);
			pc = this.localToGlobal(pc);
			if (p2.x <= pc.x && p2.y >= pc.y) {
				x1 = pc.x - cRadius; y1 = pc.y;
			}
			if (p2.x >= pc.x && p2.y >= pc.y) {
				x1 = pc.x; y1 = pc.y + cRadius;
			}
			if (p2.x >= pc.x && p2.y <= pc.y) {
				x1 = pc.x+cRadius; y1 = pc.y;
			}
			if (p2.x <= pc.x && p2.y <= pc.y) {
				x1 = pc.x; y1 = pc.y - cRadius;
			}
			var p1 = new Point(x1, y1);			
			return p1;
		}
		
		public function removeLink(link:Link):void {
			delete links[link.getId()];
		}
		///
		private function onMoveNode(event:MouseEvent):void {			
			var l:Link;
			for each(l in links){
				l.reDraw(this);
			}
		}
		
		public override function doActionOnDown():void {
			this.startDrag();
			this.illuminateObj.x = 0;
			this.illuminateObj.y = 0;
			this.addChildAt(this.illuminateObj, 0);
			parent.addEventListener(MouseEvent.MOUSE_MOVE, onMoveNode);
		}
		
		public override function doActionOnUp():void {			
			this.stopDrag();
			parent.removeEventListener(MouseEvent.MOUSE_MOVE, onMoveNode);
		}
		
		private function createCircle() {
			var circle:Sprite = new Sprite();			
			circle.graphics.lineStyle(1);
			circle.graphics.beginFill(cColour);			
			circle.graphics.drawCircle(cRadius+indent,cRadius+indent,cRadius);
			circle.graphics.endFill();
			circle.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			circle.addEventListener(MouseEvent.MOUSE_UP, onUp);
			circle.addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick);
			circle.buttonMode = true;			
			circle.useHandCursor = true;	
			circle.doubleClickEnabled = true;
			circle.hitArea = this;			
			return circle;
		}	
		
		public override function getDictDesc() {
			var cN:CNode = new CNode();
			var dictLinks:Dictionary = new Dictionary();
			var l;
			for each(l in links) {
				dictLinks[l.getId()] = l.getId();
			}
			cN.links = dictLinks;			
			//
			cN.id = this.id;
	//		cN.idBD = this.idBD;
			cN.name = this.nameElement;
			cN.description = this.description;
	//		cN.x = this.x;
	//		cN.y = this.y;			
			return cN;
		}
		
		public function toXML():String {
			var str = "<node>";
			str += "<idinscheme>" + this.id + "</idinscheme>";
			str += "<idbd>"+this.idBD+"</idbd>";
			str += "<name>"+this.name+"</name>";
			str += "<desc>" + this.description + "</desc>";
			if (this.links != null){
				str += "<links>";			
				var l;
				for each(l in this.links) {
					str += "<idlink>"+l.getId()+"</idlink>";
				}
				str += "</links>";
			}
			str += "<x>"+this.x+"</x>";
			str += "<y>"+this.y+"</y>";
			str += "</node>";
			return str;
		}
	
	}
	
}